package com.sg.xy.filter;

import com.alibaba.fastjson.JSON;
import com.sg.xy.bean.IpBrushBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author huangbingyu
 * @date 2020-09-18
 * @description
 */
@Slf4j
@Component  // 让容器扫描到，等同于注册了
public class IpAntiRoitBrushFilter implements GlobalFilter {

    private ConcurrentHashMap<String, IpBrushBean> map = new ConcurrentHashMap<>();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 从上下文中取出request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String host = request.getURI().getHost();

        // 对注册接口判断ip请求次数
        if (request.getURI().getPath().contains("/register") && ipBrush(host)) {
            log.debug("=====>host:" + host + "请求注册接口1分钟内不能超过100次");
            String data = "您频繁进⾏行行注册，请求已被拒绝";
            DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
            return response.writeWith(Mono.just(wrap));
        }

        String requestPath = request.getPath().toString();
        if(!requestPath.contains("/user/") && !requestPath.contains("/code/") ) {
            List<HttpCookie> lagou_token = request.getCookies().get("token");
            if((lagou_token == null) || (lagou_token.size() == 0)) {
                String data = "No Token! Request be denied!";
                DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
                return response.writeWith(Mono.just(wrap));
            }
        }


        return chain.filter(exchange);
    }



    /**
     * 判断对注册接口的1分钟的请求次数
     * @param host
     * @return
     */
    private boolean ipBrush(String host) {
        IpBrushBean ipBrushBean = map.get(host);
        long current = System.currentTimeMillis();
        long expireTime = current + 60 * 1000;

        if (ipBrushBean != null && expireTime > current) {
            if (ipBrushBean.getCount() < 100) {
                ipBrushBean.setCount(ipBrushBean.getCount() + 1);
            } else {
                return true;
            }
        } else {
            ipBrushBean = new IpBrushBean(host, 0, current, expireTime);
        }
        map.put(host, ipBrushBean);
        return false;
    }

}
